﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using App1AppHandler;
using Reborn_WorldServer.PendingClusterQuerys;
using Reborn_Server.App1AppHandler;

namespace Reborn_WorldServer.App1AppHandler
{
    public class CharacterManager
    {
        private List<Character> characters = new List<Character>();

        public void removeCharacter(Character character)
        {
            lock (characters)
            {
                characters.Remove(character);
            }
        }
        public void addCharacter(Character character)
        {
            lock (characters)
            {
                characters.Add(character);
            }
        }
        public bool characterExists(int userID)
        {
            lock (characters)
            {
                foreach (Character character in characters)
                {
                    if (character.UserID == userID)
                        return true;
                }
            }
            return false;
        }
        public bool clientExists(string clientID)
        {
            lock (characters)
            {
                foreach (Character character in characters)
                {
                    if (character.ClientSocket.clientId == clientID)
                        return true;
                }
            }
            return false;
        }


        public bool tryRemoveCharacter(int userID)
        {
            bool foundCharacter = false;
            lock (characters)
            {
                foreach (Character character in characters)
                {
                    if (character.UserID == userID)
                    {
                        characters.Remove(character);
                        foundCharacter = true;
                        break;
                    }
                }
            }
            return foundCharacter;
        }

        public Character getCharacter(string name)
        {
            lock (characters)
            {
                foreach (Character character in characters)
                {
                    if (character.Name.ToLower().Trim() == name.ToLower().Trim())
                        return character;
                }
            }
            return null;
        }
        public Character getCharacter(int charID)
        {
            if (charID < 0)
                return null;

            lock (characters)
            {
                foreach (Character character in characters)
                {
                    if (character.ID == charID)
                        return character;
                }
            }
            return null;
        }

        public void whoGlobal(Character character)
        {
            whoServerWide(character);
            Managers.pendingQueryManager.sendGlobalWho(new GlobalWhoRequest(character));
        }
        public void whoServerWide(Character character)
        {
            character.SendMessage("Server: Characters on server", "server");

            List<string> charactersOnline = getCharactersOnServer();
                foreach (string ctr in charactersOnline)
                    character.SendMessage(ctr, "server");
        }

        public List<string> getCharactersOnServer()
        {
            List<string> result = new List<string>();
            lock (characters)
            {
                foreach (Character ctr in characters)
                    result.Add(ctr.Name + " - " + Managers.GameHandler.GetMapName(ctr.MapID) + " (" + Managers.GameHandler.GetInstanceName(ctr.Instance) + ") [" + ctr.MapID.ToString() + " " + ctr.MapX.ToString() + " " + ctr.MapY.ToString() + "]");
            }
            return result;
        }

        public void setCharacterSkill(string name, string type, decimal level)
        {
            lock (characters)
            {
                foreach (Character character in characters)
                {
                    if (character.Name.ToLower() == name.ToLower())
                    {
                        character.skillManager.SetSkill(type, level);
                        break;
                    }
                }
            }
        }

        public void sendServerWideMessage(string message, string itemLinksXml)
        {
            lock (characters)
            {
                Message msg = new Message();
                msg.itemLinksXml = itemLinksXml;
                msg.Text = "SERVER: " + message;
                msg.CreatureID = -1;
                msg.Type = "server";

                foreach (Character character in characters)
                {
                    character.AddMessage(msg);
                    character.PlaySound("Ding", character.MapX, character.MapY);
                    character.PlaySound("Ding", character.MapX, character.MapY);
                }
            }
        }

        public void recieveJoinChannelNotification(string channel, string from)
        {
            lock (characters)
            {
                foreach (Character character in characters)
                {
                    if (character.Name.ToLower() != from.ToLower())
                        character.chatChannelManager.tryRecieveJoinNotification(channel, from);
                }
            }
        }

        public void recieveLeaveChannelNotification(string channel, string from)
        {
            lock (characters)
            {
                foreach (Character character in characters)
                {
                    if (character.Name.ToLower() != from.ToLower())
                        character.chatChannelManager.tryRecieveLeaveNotification(channel, from);
                }
            }
        }

        public void recieveChannelMessage(string channel, string from, string message, string itemlinksXml)
        {
            lock (characters)
            {
                foreach (Character character in characters)
                    character.chatChannelManager.tryRecieveMessage(channel, from, message, itemlinksXml);
            }
        }

        public void sendGlobalMessage(string message, string itemLinksXml)
        {
            sendServerWideMessage(message, itemLinksXml);
            Managers.BeginSendToPrimary("<globalmessage><txt>" + Message.escapeXmlText(message) + "</txt>" + itemLinksXml + "</globalmessage>");
        }

        

        public void sendFriendOnline(int characterId)
        {
            //Send this update out to everyone on this server first
            recieveFriendOnline(characterId);

            //Notify the primary that this person came online so it can notify the other servers.
            Managers.BeginSendToPrimary("<friendonline id=\"" + characterId.ToString() + "\" />");
        }
        public void recieveFriendOnline(int characterId)
        {
            lock (characters)
            {
                foreach (Character character in characters)
                    character.friendsManager.friendOnline(characterId);
            }
        }
        public void recieveNewMail(int characterId)
        {
            lock (characters)
            {
                foreach (Character character in characters)
                {
                    if (character.ID == characterId)
                    {
                        character.SendMessage("You have new mail.", "server");
                        break;
                    }
                }
            }
        }


        public void recieveKarmaNotification(int characterId)
        {
            Character charToUpdate = null;
            lock (characters)
            {
                foreach (Character character in characters)
                {
                    if (character.ID == characterId)
                    {
                        charToUpdate = character;
                        break;
                    }
                }
            }
            if (charToUpdate != null)
                charToUpdate.UpdateKarma(true);
        }

        public void sendFriendOffline(int characterId)
        {
            //Send this update out to everyone on this server first
            recieveFriendOffline(characterId);

            //Notify the primary that this person came online so it can notify the other servers.
            Managers.BeginSendToPrimary("<friendoffline id=\"" + characterId.ToString() + "\" />");
        }
        public void recieveFriendOffline(int characterId)
        {
            lock (characters)
            {
                foreach (Character character in characters)
                    character.friendsManager.friendOffline(characterId);
            }
        }
    }
}
